package com.shh.shojbackendjudgeservice.utils;



import com.shh.shojbackendmodel.model.codesandbox.ExecuteMessage;
import org.springframework.util.StopWatch;

import java.io.BufferedReader;
import java.io.InputStreamReader;

/**
 * 统一处理进程返回信息的类 把要封装的方法都写在这里 不确定要哪些类型的话先复制进来爆红的就是需要的类型
 */
public class ProcessUtils {
    /**
     * 执行进程并获取信息
     * @param runProcess
     * @param opName
     * @return
     */
    public static ExecuteMessage runProcessAndGetMessage(Process runProcess, String opName){
        ExecuteMessage executeMessage = new ExecuteMessage();
        try {
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            //等待编译完成
            //等待编译完成
            int exitValue = runProcess.waitFor();
            executeMessage.setExitValue(exitValue);
            //正常编译完成
            if(exitValue== 0){
                //执行class文件
                System.out.println(opName + "成功");
                // 分批获取进程的正常输出
                //getInputStream() 读取进程的输出（从进程的角度看是输出，从Java程序的角度看是输入） 文本类型字节流(二进制)
                //InputStreamReader 将原始的字节流 InputStream 转换为字符流 Reader。
                //BufferedReader 缓冲字符输入流，可以一次读取一行 减少IO操作 提升性能
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(runProcess.getInputStream()));
                //拼接
                //为什么使用StringBuilder？ 为什么使用StringBuilder拼接和String有什么区别？
                //首先String类型是不可变类型，每次修改都会产生新的String对象，而StringBuilder是可变类型，可以直接修改原对象，节省内存,线程不安全但性能更高。
                //StringBuilder适用于对线程安全要求不高,频繁修改拼接字符串的场景 String相反
                StringBuilder compileOutputStringBuilder = new StringBuilder();
                // 逐行读取
                String compileOutputLine;
                while ((compileOutputLine = bufferedReader.readLine()) != null) {
                    //拼接
                    compileOutputStringBuilder.append(compileOutputLine);
                }
                executeMessage.setMessage(compileOutputStringBuilder.toString());
            }else{
                System.out.println(opName + "失败"  + exitValue);
                // 分批获取进程的正常输出
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(runProcess.getInputStream()));
                StringBuilder compileOutputStringBuilder = new StringBuilder();
                // 逐行读取
                String compileOutputLine;
                while ((compileOutputLine = bufferedReader.readLine()) != null) {
                    compileOutputStringBuilder.append(compileOutputLine);
                }
                // 分批获取进程的错误输出
                BufferedReader errorBufferedReader = new BufferedReader(new InputStreamReader(runProcess.getErrorStream()));
                StringBuilder errorCompileOutputStringBuilder = new StringBuilder();

                // 逐行读取
                String errorCompileOutputLine;
                while ((errorCompileOutputLine = errorBufferedReader.readLine()) != null) {
                    errorCompileOutputStringBuilder.append(errorCompileOutputLine);
                }
                executeMessage.setErrorMessage(errorCompileOutputStringBuilder.toString());
            }
            stopWatch.stop();
            executeMessage.setTime(stopWatch.getLastTaskTimeMillis());
        }catch (Exception e){
            e.printStackTrace();
        }

        return executeMessage;
    }

    /**
     * 执行交互式进程并获取信息
     * @param runProcess
     * @param opName
     * @return
     */

    public static ExecuteMessage runInteractProcessAndGetMessage(Process runProcess,String opName){
        ExecuteMessage executeMessage = new ExecuteMessage();
        try {
            //等待编译完成
            int exitValue = runProcess.waitFor();
            executeMessage.setExitValue(exitValue);
            //正常编译完成
            if(exitValue== 0){
                //执行class文件
                System.out.println(opName + "成功");
                // 分批获取进程的正常输出
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(runProcess.getInputStream()));
                //拼接
                StringBuilder compileOutputStringBuilder = new StringBuilder();
                // 逐行读取
                String compileOutputLine;
                while ((compileOutputLine = bufferedReader.readLine()) != null) {
                    //拼接
                    compileOutputStringBuilder.append(compileOutputLine);
                }
                executeMessage.setMessage(compileOutputStringBuilder.toString());
            }else{
                System.out.println(opName + "失败"  + exitValue);
                // 分批获取进程的正常输出
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(runProcess.getInputStream()));
                StringBuilder compileOutputStringBuilder = new StringBuilder();
                // 逐行读取
                String compileOutputLine;
                while ((compileOutputLine = bufferedReader.readLine()) != null) {
                    compileOutputStringBuilder.append(compileOutputLine);
                }
                // 分批获取进程的错误输出
                BufferedReader errorBufferedReader = new BufferedReader(new InputStreamReader(runProcess.getErrorStream()));
                StringBuilder errorCompileOutputStringBuilder = new StringBuilder();

                // 逐行读取
                String errorCompileOutputLine;
                while ((errorCompileOutputLine = errorBufferedReader.readLine()) != null) {
                    errorCompileOutputStringBuilder.append(errorCompileOutputLine);
                }
                executeMessage.setErrorMessage(errorCompileOutputStringBuilder.toString());
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return executeMessage;
    }
}
